<template>
    <!-- 组件的根容器，类名为 demo_preview -->
    <div class="demo_preview">
        <!-- 预览区域容器，用于展示组件示例 -->
        <div class="preview_box">
            <!-- 插槽，用于插入需要预览的组件内容 -->
            <slot />
        </div>
        <!-- 代码展示区域容器 -->
        <div class="code_box">
            <!-- 代码展示区域，根据 showCode 状态添加 show_code 类 -->
            <div class="code" :class="{ show_code: showCode }">
                <!-- 代码参考区域 -->
                <div class="code__reference">
                    <!-- 代码内容区域 -->
                    <div class="code_content">
                        <!-- 使用 highlightjs 组件进行代码高亮，自动检测语言并传入源代码 -->
                        <highlightjs autodetect :code="sourceCode" />
                    </div>
                </div>
            </div>
            <!-- 操作按钮，点击切换代码显示/隐藏状态 -->
            <div class="operate_btn" @click="handleClick">{{ showCode ? "隐藏" : "显示" }}代码</div>
        </div>
    </div>
</template>

<script setup>
// 从 vue 库中导入 onMounted、reactive 和 toRefs 函数
import { onMounted, reactive, toRefs } from "vue";
// 导入代码高亮库
import "highlight.js";

/**
 * 定义组件的 props
 * @property {string} compName - 组件名称，默认值为空字符串
 * @property {string} demoName - 示例名称，默认值为空字符串
 */
const props = defineProps({
    compName: {
        type: String,
        default: "",
    },
    demoName: {
        type: String,
        default: "",
    },
});

// 在组件挂载后执行 componentCode 函数
onMounted(() => {
    componentCode();
});

// 使用 reactive 创建响应式对象 state
const state = reactive({
    sourceCode: "", // 存储组件源代码
    showCode: false, // 控制代码是否显示
    demoHTML: "", // 存储示例的 HTML 代码
});

// 将 state 对象的属性转换为响应式引用
const { sourceCode, showCode, demoHTML } = toRefs(state);

/**
 * 异步获取组件源代码的函数
 */
const componentCode = async () => {
    // 动态导入指定组件的 Vue 文件内容
    const data = await import(`../../../components/${props.compName}/${props.demoName}.vue?raw`);
    // 将导入的源代码赋值给 state.sourceCode
    state.sourceCode = data.default;
};

/**
 * 处理点击事件，切换代码显示/隐藏状态
 */
const handleClick = () => {
    // 取反 showCode 状态
    state.showCode = !state.showCode;
};
</script>

<style scoped>
/* 组件根容器样式 */
.demo_preview {
    margin: 20px 0;
    border: 1px solid #efefef;
    border-radius: 6px;
    overflow: hidden;
}

/* 预览区域容器样式 */
.preview_box {
    padding: 20px;
}

/* 操作按钮样式 */
.operate_btn {
    position: relative;
    height: 46px;
    line-height: 46px;
    color: #666;
    text-align: center;
    background: #f7f7f7;
    cursor: pointer;
    z-index: 100;
}

/* 操作按钮悬停样式 */
.operate_btn:hover {
    background: #f2f2f2;
}

/* 代码展示区域样式 */
.code {
    border-top: 1px solid #efefef;
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows 0.3s ease;
}

/* 代码参考区域样式 */
.code .code__reference {
    overflow: hidden;
}

/* 代码显示状态下的样式 */
.show_code {
    grid-template-rows: 1fr;
}
</style>